﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Web;
using viBlog.Classes;
using viBlog.Controllers;
using visinia.SmartEngine;
using visinia.SmartEngine.Modules;
using visinia.SmartEngine.Site;

public partial class Modules_viBlog_PostsList_PostsList : WebModule
{
    protected void Page_Load(object sender, EventArgs e)
    {        
        // SEO            
        WebPageController.AddTitle(Page, BlogController.BlogName);
        WebPageController.AddMetaTag(Page, WebPageController.MetaTag.Description, BlogController.BlogTagLine);
        //SeoController.AddMetaTag(Page, SeoController.MetaTags.author, );
        List<string> tagNames = TagController.GetTags().ConvertAll(
                                new Converter<Tag, string>(GetTagName));
        string tagKeywords = string.Join(",", tagNames.ToArray());
        List<string> categoryNames = CategoryController.GetCategories().ConvertAll(
                                new Converter<Category, string>(GetCategoryName));
        string categoryKeywords = string.Join(",", categoryNames.ToArray());
        string keywords = "";
        if (string.IsNullOrEmpty(tagKeywords))
            keywords = categoryKeywords;
        else
            keywords = tagKeywords + "," + categoryKeywords;
        if (!string.IsNullOrEmpty(keywords))
            WebPageController.AddMetaTag(Page, WebPageController.MetaTag.Keywords, keywords);
        WebPageController.AddRssFeedLink(Page, BlogController.BlogName + "(RSS)", WebRoots.GetWebRoot + BlogController.BlogUrlSeparator + "/rss.aspx");
        Bind();
    }

    private void Bind()
    {
        if (!string.IsNullOrEmpty(Request.QueryString["PostId"]))
        {
            int postid = 0;
            if (Int32.TryParse(Request.QueryString["PostId"], out postid))
            {   // show full post                    
                DisplaySinglePost(PostController.GetPost(postid));
            }
        }
        else if (!string.IsNullOrEmpty(Request.QueryString["Category"]))
        {
            Category category = CategoryController.GetCategory(Request.QueryString["Category"]);
            if (category != null)
            {
                DisplayPostsByCategory(category);
            }
        }
        else if (!string.IsNullOrEmpty(Request.QueryString["Tag"]))
        {
            Tag tag = TagController.GetTag(Request.QueryString["Tag"]);
            if (tag != null)
            {
                DisplayPostsByTag(tag);
            }
        }
        else if ((!string.IsNullOrEmpty(Request.QueryString["Year"])) && (!string.IsNullOrEmpty(Request.QueryString["Month"])))
        {
            int year = 0;
            if (Int32.TryParse(Request.QueryString["Year"], out year))
            {
                int month = 0;
                if (Int32.TryParse(Request.QueryString["Month"], out month))
                {
                    DateTime date = new DateTime(year, month, 1);
                    DisplayPostsByDate(date);
                }
            }
        }
        else
            DisplayLatestPosts();
    }

    private void DisplayPostsByDate(DateTime date)
    {
        int total = PostController.GetPostsCount(date);
        int pages = total / BlogController.PostsCountPerPage;
        if ((total % BlogController.PostsCountPerPage) > 0)
            ++pages;
        --pages;//to make pages zero based    
        int requestedPage = 0;
        Int32.TryParse(Request.QueryString["ArchivePage"], out requestedPage);
        if (pages >= requestedPage)
        {
            pager_NextLink.NavigateUrl = WebRoots.GetWebRoot + BlogController.BlogUrlSeparator + "/Archive/" + date.Year + "/" + date.Month + "/Page/" + (requestedPage + 1) + ".aspx";
            pager_HomeLink.NavigateUrl = WebRoots.GetWebRoot + BlogController.BlogUrlSeparator + "/Archive/" + date.Year + "/" + date.Month + ".aspx";
            pager_PrevLink.NavigateUrl = WebRoots.GetWebRoot + BlogController.BlogUrlSeparator + "/Archive/" + date.Year + "/" + date.Month + "/Page/" + (requestedPage - 1) + ".aspx";
            PagerVisibility(pages, requestedPage);
            int AccessCount = (BlogController.PostsCountPerPage * requestedPage) + BlogController.PostsCountPerPage;
            int DisplayedCount = BlogController.PostsCountPerPage * requestedPage;
            List<Post> list = PostController.GetPosts(date);
            if (list.Count < AccessCount)
                DisplayPosts(list.GetRange(BlogController.PostsCountPerPage * requestedPage, list.Count - DisplayedCount));
            else
                DisplayPosts(list.GetRange(BlogController.PostsCountPerPage * requestedPage, BlogController.PostsCountPerPage));
        }
    }

    private void DisplayPostsByTag(Tag tag)
    {
        int total = PostController.GetPostsCount(tag);
        int pages = total / BlogController.PostsCountPerPage;
        if ((total % BlogController.PostsCountPerPage) > 0)
            ++pages;
        --pages;//to make pages zero based  
        int requestedPage = 0;
        Int32.TryParse(Request.QueryString["TagPage"], out requestedPage);
        if (pages >= requestedPage)
        {
            pager_NextLink.NavigateUrl = WebRoots.GetWebRoot + BlogController.BlogUrlSeparator + "/Tag/" + HttpUtility.UrlEncode(tag.Name) + "/Page/" + (requestedPage + 1) + ".aspx";
            pager_HomeLink.NavigateUrl = WebRoots.GetWebRoot + BlogController.BlogUrlSeparator + "/Tag/" + HttpUtility.UrlEncode(tag.Name) + ".aspx";
            pager_PrevLink.NavigateUrl = WebRoots.GetWebRoot + BlogController.BlogUrlSeparator + "/Tag/" + HttpUtility.UrlEncode(tag.Name) + "/Page/" + (requestedPage - 1) + ".aspx";
            PagerVisibility(pages, requestedPage);
            int AccessCount = (BlogController.PostsCountPerPage * requestedPage) + BlogController.PostsCountPerPage;
            int DisplayedCount = BlogController.PostsCountPerPage * requestedPage;
            List<Post> list = PostController.GetPosts(tag, AccessCount);
            if (list.Count < AccessCount)
                DisplayPosts(list.GetRange(BlogController.PostsCountPerPage * requestedPage, list.Count - DisplayedCount));
            else
                DisplayPosts(list.GetRange(BlogController.PostsCountPerPage * requestedPage, BlogController.PostsCountPerPage));
        }
    }

    private void DisplayPostsByCategory(Category category)
    {
        int total = PostController.GetPostsCount(category);
        int pages = total / BlogController.PostsCountPerPage;
        if ((total % BlogController.PostsCountPerPage) > 0)
            ++pages;
        --pages;//to make pages zero based 
        int requestedPage = 0;
        Int32.TryParse(Request.QueryString["CategoryPage"], out requestedPage);
        if (pages >= requestedPage)
        {
            pager_NextLink.NavigateUrl = WebRoots.GetWebRoot + BlogController.BlogUrlSeparator + "/Category/" + HttpUtility.UrlEncode(category.Name) + "/Page/" + (requestedPage + 1) + ".aspx";
            pager_HomeLink.NavigateUrl = WebRoots.GetWebRoot + BlogController.BlogUrlSeparator + "/Category/" + HttpUtility.UrlEncode(category.Name) + ".aspx";
            pager_PrevLink.NavigateUrl = WebRoots.GetWebRoot + BlogController.BlogUrlSeparator + "/Category/" + HttpUtility.UrlEncode(category.Name) + "/Page/" + (requestedPage - 1) + ".aspx";
            PagerVisibility(pages, requestedPage);
            PagerVisibility(pages, requestedPage);
            int AccessCount = (BlogController.PostsCountPerPage * requestedPage) + BlogController.PostsCountPerPage;
            int DisplayedCount = BlogController.PostsCountPerPage * requestedPage;
            List<Post> list = PostController.GetPosts(category, AccessCount);
            if (list.Count < AccessCount)
                DisplayPosts(list.GetRange(BlogController.PostsCountPerPage * requestedPage, list.Count - DisplayedCount));
            else
                DisplayPosts(list.GetRange(BlogController.PostsCountPerPage * requestedPage, BlogController.PostsCountPerPage));
        }
    }

    private void DisplayLatestPosts()
    {
        int total = PostController.GetPostsCount();
        int pages = total / BlogController.PostsCountPerPage;
        if ((total % BlogController.PostsCountPerPage) > 0)
            ++pages;
        --pages;//to make pages zero based   
        int requestedPage = 0;
        Int32.TryParse(Request.QueryString["PostsPage"], out requestedPage);
        if (pages >= requestedPage)
        {
            pager_NextLink.NavigateUrl = WebRoots.GetWebRoot + BlogController.BlogUrlSeparator + "/Page/" + (requestedPage + 1) + ".aspx";
            pager_HomeLink.NavigateUrl = WebRoots.GetWebRoot + BlogController.BlogUrlSeparator + ".aspx";
            pager_PrevLink.NavigateUrl = WebRoots.GetWebRoot + BlogController.BlogUrlSeparator + "/Page/" + (requestedPage - 1) + ".aspx";
            PagerVisibility(pages, requestedPage);
            int AccessCount = (BlogController.PostsCountPerPage * requestedPage) + BlogController.PostsCountPerPage;
            int DisplayedCount = BlogController.PostsCountPerPage * requestedPage;
            List<Post> list = PostController.GetPosts(AccessCount);
            if (list.Count < AccessCount)
                DisplayPosts(list.GetRange(BlogController.PostsCountPerPage * requestedPage, list.Count - DisplayedCount));
            else
                DisplayPosts(list.GetRange(BlogController.PostsCountPerPage * requestedPage, BlogController.PostsCountPerPage));
        }
    }

    private void PagerVisibility(int pages, int requestedPage)
    {
        if (pages > requestedPage)
        {
            pager_NextLink.Visible = true;
        }
        if (requestedPage > 0)
        {
            pager_HomeLink.Visible = true;
            pager_PrevLink.Visible = true;
        }
    }

    private void DisplaySinglePost(Post post)
    {
        if (post != null)
        {
            PostView view = (PostView)LoadControl(GetPostView());
            view.Post = post;
            view.ShowFullPost = true;
            view.ShowAds = true;
            view.Ads = (string)Settings["Ads"];
            POSTS_LIST.Controls.Add(view);

            // SEO  
            WebPageController.AddTitle(Page, post.Title);
            WebPageController.AddMetaTag(Page, WebPageController.MetaTag.Description, WebHelpers.StripHtml(post.Summary));
            WebPageController.AddMetaTag(Page, WebPageController.MetaTag.Author, post.Author);
            List<string> tagNames = TagController.GetTags(post.PostId).ConvertAll(
                                    new Converter<Tag, string>(GetTagName));
            string tagKeywords = string.Join(",", tagNames.ToArray());
            List<string> categoryNames = CategoryController.GetCategories(post.PostId).ConvertAll(
                                    new Converter<Category, string>(GetCategoryName));
            string categoryKeywords = string.Join(",", categoryNames.ToArray());
            string allKeywords = "";
            if (string.IsNullOrEmpty(tagKeywords))
                allKeywords = categoryKeywords;
            else
                allKeywords = tagKeywords + "," + categoryKeywords;
            string keywords = RemoveDuplicateStrings(allKeywords);
            if (!string.IsNullOrEmpty(keywords))
                WebPageController.AddMetaTag(Page, WebPageController.MetaTag.Keywords, keywords);
            WebPageController.AddRssFeedLink(Page, BlogController.BlogName + "(RSS)", WebRoots.GetWebRoot + BlogController.BlogUrlSeparator + "/rss.aspx");

            // may be this also work for SEO            
            PostRelatives postRelatives = PostController.GetPostRelatives(post.PostId);
            if (postRelatives != null)
            {
                //previous
                Post previousPost = PostController.GetPost(postRelatives.PreviousPostId);
                if (previousPost != null)
                    WebPageController.AddHeadLink(Page, previousPost.Title, previousPost.Url, "prev");
                // nest
                Post nextPost = PostController.GetPost(postRelatives.NextPostId);
                if (nextPost != null)
                    WebPageController.AddHeadLink(Page, nextPost.Title, nextPost.Url, "next");
                //start
                Post firstPost = PostController.GetPost(postRelatives.FirstPostId);
                if (firstPost != null)
                    WebPageController.AddHeadLink(Page, firstPost.Title, firstPost.Url, "first");
                // last
                Post lastPost = PostController.GetPost(postRelatives.LastPostId);
                if (lastPost != null)
                    WebPageController.AddHeadLink(Page, lastPost.Title, lastPost.Url, "last");
                //start
                string url = WebRoots.GetWebRoot + BlogController.BlogUrlSeparator + ".aspx";
                WebPageController.AddHeadLink(Page, BlogController.BlogName, url, "start");
            }
        }
    }

    private string GetPostView()
    {
        // search for the PostView.ascx 
        // 1 search in the current active theme folder
        //   if not found then
        // 2 search in the current folder

        string currentThemeDir = Server.MapPath(WebRoots.GetThemesRoot) + SiteSettings.Theme;
        string file = currentThemeDir + "\\viBlog.PostView.ascx";
        if (File.Exists(file))
            return WebRoots.GetThemesRoot + SiteSettings.Theme + "/viBlog.PostView.ascx";
        else
            return "viBlog.PostView.ascx";
    }

    private string RemoveDuplicateStrings(string keywords)
    {
        List<string> pureKeywords = new List<string>();
        string[] strings = keywords.Split(',');
        foreach (string keyword in strings)
        {
            if (!pureKeywords.Contains(keyword))
                pureKeywords.Add(keyword);
        }
        return string.Join(",", pureKeywords.ToArray());
    }

    private static string GetTagName(Tag tag)
    {
        return tag.Name;
    }

    private static string GetCategoryName(Category category)
    {
        return category.Name;
    }

    private void DisplayPosts(List<Post> posts)
    {
        POSTS_LIST.Controls.Clear();
        foreach (Post post in posts)
        {
            PostView view = (PostView)LoadControl(GetPostView());
            view.Post = post;
            POSTS_LIST.Controls.Add(view);
        }
    }
}
